home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / cclimber.c < prev    next >
C/C++ Source or Header  |  2000-05-04  |  17KB  |  718 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. ***************************************************************************/
  8.  
  9. #include "driver.h"
  10. #include "vidhrdw/generic.h"
  11.  
  12.  
  13.  
  14. #define BIGSPRITE_WIDTH 128
  15. #define BIGSPRITE_HEIGHT 128
  16.  
  17. unsigned char *cclimber_bsvideoram;
  18. size_t cclimber_bsvideoram_size;
  19. unsigned char *cclimber_bigspriteram;
  20. unsigned char *cclimber_column_scroll;
  21. static unsigned char *bsdirtybuffer;
  22. static struct osd_bitmap *bsbitmap;
  23. static int flipscreen[2];
  24. static int palettebank;
  25. static int sidepanel_enabled;
  26. static int bgpen;
  27.  
  28.  
  29. /***************************************************************************
  30.  
  31.   Convert the color PROMs into a more useable format.
  32.  
  33.   Crazy Climber has three 32x8 palette PROMs.
  34.   The palette PROMs are connected to the RGB output this way:
  35.  
  36.   bit 7 -- 220 ohm resistor  -- BLUE
  37.         -- 470 ohm resistor  -- BLUE
  38.         -- 220 ohm resistor  -- GREEN
  39.         -- 470 ohm resistor  -- GREEN
  40.         -- 1  kohm resistor  -- GREEN
  41.         -- 220 ohm resistor  -- RED
  42.         -- 470 ohm resistor  -- RED
  43.   bit 0 -- 1  kohm resistor  -- RED
  44.  
  45. ***************************************************************************/
  46. void cclimber_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
  47. {
  48.     int i;
  49.     #define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
  50.     #define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + (offs)])
  51.  
  52.  
  53.     for (i = 0;i < Machine->drv->total_colors;i++)
  54.     {
  55.         int bit0,bit1,bit2;
  56.  
  57.  
  58.         /* red component */
  59.         bit0 = (*color_prom >> 0) & 0x01;
  60.         bit1 = (*color_prom >> 1) & 0x01;
  61.         bit2 = (*color_prom >> 2) & 0x01;
  62.         *(palette++) = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
  63.         /* green component */
  64.         bit0 = (*color_prom >> 3) & 0x01;
  65.         bit1 = (*color_prom >> 4) & 0x01;
  66.         bit2 = (*color_prom >> 5) & 0x01;
  67.         *(palette++) = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
  68.         /* blue component */
  69.         bit0 = 0;
  70.         bit1 = (*color_prom >> 6) & 0x01;
  71.         bit2 = (*color_prom >> 7) & 0x01;
  72.         *(palette++) = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
  73.  
  74.         color_prom++;
  75.     }
  76.  
  77.  
  78.     /* character and sprite lookup table */
  79.     /* they use colors 0-63 */
  80.     for (i = 0;i < TOTAL_COLORS(0);i++)
  81.     {
  82.         /* pen 0 always uses color 0 (background in River Patrol and Silver Land) */
  83.         if (i % 4 == 0) COLOR(0,i) = 0;
  84.         else COLOR(0,i) = i;
  85.     }
  86.  
  87.     /* big sprite lookup table */
  88.     /* it uses colors 64-95 */
  89.     for (i = 0;i < TOTAL_COLORS(2);i++)
  90.     {
  91.         if (i % 4 == 0) COLOR(2,i) = 0;
  92.         else COLOR(2,i) = i + 64;
  93.     }
  94.  
  95.     bgpen = 0;
  96. }
  97.  
  98.  
  99. /***************************************************************************
  100.  
  101.   Convert the color PROMs into a more useable format.
  102.  
  103.   Swimmer has two 256x4 char/sprite palette PROMs and one 32x8 big sprite
  104.   palette PROM.
  105.   The palette PROMs are connected to the RGB output this way:
  106.   (the 500 and 250 ohm resistors are made of 1 kohm resistors in parallel)
  107.  
  108.   bit 3 -- 250 ohm resistor  -- BLUE
  109.         -- 500 ohm resistor  -- BLUE
  110.         -- 250 ohm resistor  -- GREEN
  111.   bit 0 -- 500 ohm resistor  -- GREEN
  112.   bit 3 -- 1  kohm resistor  -- GREEN
  113.         -- 250 ohm resistor  -- RED
  114.         -- 500 ohm resistor  -- RED
  115.   bit 0 -- 1  kohm resistor  -- RED
  116.  
  117.   bit 7 -- 250 ohm resistor  -- BLUE
  118.         -- 500 ohm resistor  -- BLUE
  119.         -- 250 ohm resistor  -- GREEN
  120.         -- 500 ohm resistor  -- GREEN
  121.         -- 1  kohm resistor  -- GREEN
  122.         -- 250 ohm resistor  -- RED
  123.         -- 500 ohm resistor  -- RED
  124.   bit 0 -- 1  kohm resistor  -- RED
  125.  
  126.   Additionally, the background color of the score panel is determined by
  127.   these resistors:
  128.  
  129.                   /--- tri-state --  470 -- BLUE
  130.   +5V -- 1kohm ------- tri-state --  390 -- GREEN
  131.                   \--- tri-state -- 1000 -- RED
  132.  
  133. ***************************************************************************/
  134.  
  135. #define BGPEN (256+32)
  136. #define SIDEPEN (256+32+1)
  137.  
  138. void swimmer_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
  139. {
  140.     int i;
  141.     #define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
  142.     #define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + (offs)])
  143.  
  144.  
  145.     for (i = 0;i < 256;i++)
  146.     {
  147.         int bit0,bit1,bit2;
  148.  
  149.  
  150.         /* red component */
  151.         bit0 = (color_prom[i] >> 0) & 0x01;
  152.         bit1 = (color_prom[i] >> 1) & 0x01;
  153.         bit2 = (color_prom[i] >> 2) & 0x01;
  154.         *(palette++) = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
  155.         /* green component */
  156.         bit0 = (color_prom[i] >> 3) & 0x01;
  157.         bit1 = (color_prom[i+256] >> 0) & 0x01;
  158.         bit2 = (color_prom[i+256] >> 1) & 0x01;
  159.         *(palette++) = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
  160.         /* blue component */
  161.         bit0 = 0;
  162.         bit1 = (color_prom[i+256] >> 2) & 0x01;
  163.         bit2 = (color_prom[i+256] >> 3) & 0x01;
  164.         *(palette++) = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
  165.  
  166.         /* side panel */
  167.         if (i % 8)
  168.         {
  169.             COLOR(0,i) = i;
  170.             COLOR(0,i+256) = i;
  171.         }
  172.         else
  173.         {
  174.             /* background */
  175.             COLOR(0,i) = BGPEN;
  176.             COLOR(0,i+256) = SIDEPEN;
  177.         }
  178.     }
  179.  
  180.     color_prom += 2 * 256;
  181.  
  182.     /* big sprite */
  183.     for (i = 0;i < 32;i++)
  184.     {
  185.         int bit0,bit1,bit2;
  186.  
  187.  
  188.         /* red component */
  189.         bit0 = (color_prom[i] >> 0) & 0x01;
  190.         bit1 = (color_prom[i] >> 1) & 0x01;
  191.         bit2 = (color_prom[i] >> 2) & 0x01;
  192.         *(palette++) = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
  193.         /* green component */
  194.         bit0 = (color_prom[i] >> 3) & 0x01;
  195.         bit1 = (color_prom[i] >> 4) & 0x01;
  196.         bit2 = (color_prom[i] >> 5) & 0x01;
  197.         *(palette++) = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
  198.         /* blue component */
  199.         bit0 = 0;
  200.         bit1 = (color_prom[i] >> 6) & 0x01;
  201.         bit2 = (color_prom[i] >> 7) & 0x01;
  202.         *(palette++) = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
  203.  
  204.         if (i % 8 == 0) COLOR(2,i) = BGPEN;  /* enforce transparency */
  205.         else COLOR(2,i) = i+256;
  206.     }
  207.  
  208.     /* background */
  209.     *(palette++) = 0;
  210.     *(palette++) = 0;
  211.     *(palette++) = 0;
  212.     /* side panel background color */
  213.     *(palette++) = 0x24;
  214.     *(palette++) = 0x5d;
  215.     *(palette++) = 0x4e;
  216.  
  217.     palette_transparent_color = BGPEN; /* background color */
  218.     bgpen = BGPEN;
  219. }
  220.  
  221.  
  222.  
  223. /***************************************************************************
  224.  
  225.   Swimmer can directly set the background color.
  226.   The latch is connected to the RGB output this way:
  227.   (the 500 and 250 ohm resistors are made of 1 kohm resistors in parallel)
  228.  
  229.   bit 7 -- 250 ohm resistor  -- RED
  230.         -- 500 ohm resistor  -- RED
  231.         -- 250 ohm resistor  -- GREEN
  232.         -- 500 ohm resistor  -- GREEN
  233.         -- 1  kohm resistor  -- GREEN
  234.         -- 250 ohm resistor  -- BLUE
  235.         -- 500 ohm resistor  -- BLUE
  236.   bit 0 -- 1  kohm resistor  -- BLUE
  237.  
  238. ***************************************************************************/
  239. WRITE_HANDLER( swimmer_bgcolor_w )
  240. {
  241.     int bit0,bit1,bit2;
  242.     int r,g,b;
  243.  
  244.  
  245.     /* red component */
  246.     bit0 = 0;
  247.     bit1 = (data >> 6) & 0x01;
  248.     bit2 = (data >> 7) & 0x01;
  249.     r = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
  250.  
  251.     /* green component */
  252.     bit0 = (data >> 3) & 0x01;
  253.     bit1 = (data >> 4) & 0x01;
  254.     bit2 = (data >> 5) & 0x01;
  255.     g = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
  256.  
  257.     /* blue component */
  258.     bit0 = (data >> 0) & 0x01;
  259.     bit1 = (data >> 1) & 0x01;
  260.     bit2 = (data >> 2) & 0x01;
  261.     b = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
  262.  
  263.     palette_change_color(BGPEN,r,g,b);
  264. }
  265.  
  266.  
  267.  
  268. /***************************************************************************
  269.  
  270.   Start the video hardware emulation.
  271.  
  272. ***************************************************************************/
  273. int cclimber_vh_start(void)
  274. {
  275.     if (generic_vh_start() != 0)
  276.         return 1;
  277.  
  278.     if ((bsdirtybuffer = malloc(cclimber_bsvideoram_size)) == 0)
  279.     {
  280.         generic_vh_stop();
  281.         return 1;
  282.     }
  283.     memset(bsdirtybuffer,1,cclimber_bsvideoram_size);
  284.  
  285.     if ((bsbitmap = osd_create_bitmap(BIGSPRITE_WIDTH,BIGSPRITE_HEIGHT)) == 0)
  286.     {
  287.         free(bsdirtybuffer);
  288.         generic_vh_stop();
  289.         return 1;
  290.     }
  291.  
  292.     return 0;
  293. }
  294.  
  295.  
  296.  
  297. /***************************************************************************
  298.  
  299.   Stop the video hardware emulation.
  300.  
  301. ***************************************************************************/
  302. void cclimber_vh_stop(void)
  303. {
  304.     osd_free_bitmap(bsbitmap);
  305.     free(bsdirtybuffer);
  306.     generic_vh_stop();
  307. }
  308.  
  309.  
  310.  
  311. WRITE_HANDLER( cclimber_flipscreen_w )
  312. {
  313.     if (flipscreen[offset] != (data & 1))
  314.     {
  315.         flipscreen[offset] = data & 1;
  316.         memset(dirtybuffer,1,videoram_size);
  317.     }
  318. }
  319.  
  320.  
  321.  
  322. WRITE_HANDLER( cclimber_colorram_w )
  323. {
  324.     if (colorram[offset] != data)
  325.     {
  326.         /* bit 5 of the address is not used for color memory. There is just */
  327.         /* 512 bytes of memory; every two consecutive rows share the same memory */
  328.         /* region. */
  329.         offset &= 0xffdf;
  330.  
  331.         dirtybuffer[offset] = 1;
  332.         dirtybuffer[offset + 0x20] = 1;
  333.  
  334.         colorram[offset] = data;
  335.         colorram[offset + 0x20] = data;
  336.     }
  337. }
  338.  
  339.  
  340.  
  341. WRITE_HANDLER( cclimber_bigsprite_videoram_w )
  342. {
  343.     if (cclimber_bsvideoram[offset] != data)
  344.     {
  345.         bsdirtybuffer[offset] = 1;
  346.  
  347.         cclimber_bsvideoram[offset] = data;
  348.     }
  349. }
  350.  
  351.  
  352.  
  353. WRITE_HANDLER( swimmer_palettebank_w )
  354. {
  355.     if (palettebank != (data & 1))
  356.     {
  357.         palettebank = data & 1;
  358.         memset(dirtybuffer,1,videoram_size);
  359.     }
  360. }
  361.  
  362.  
  363.  
  364. WRITE_HANDLER( swimmer_sidepanel_enable_w )
  365. {
  366.     if (data != sidepanel_enabled)
  367.     {
  368.         sidepanel_enabled = data;
  369.  
  370.         /* We only need to dirty the side panel, but this location is not */
  371.         /* written to very often, so we just dirty the whole screen */
  372.         memset(dirtybuffer,1,videoram_size);
  373.     }
  374. }
  375.  
  376.  
  377.  
  378. /***************************************************************************
  379.  
  380.   Draw the game screen in the given osd_bitmap.
  381.   Do NOT call osd_update_display() from this function, it will be called by
  382.   the main emulation engine.
  383.  
  384. ***************************************************************************/
  385. static void drawbigsprite(struct osd_bitmap *bitmap)
  386. {
  387.     int sx,sy,flipx,flipy;
  388.  
  389.  
  390.     sx = 136 - cclimber_bigspriteram[3];
  391.     sy = 128 - cclimber_bigspriteram[2];
  392.     flipx = cclimber_bigspriteram[1] & 0x10;
  393.     flipy = cclimber_bigspriteram[1] & 0x20;
  394.     if (flipscreen[1])      /* only the Y direction has to be flipped */
  395.     {
  396.         sy = 128 - sy;
  397.         flipy = !flipy;
  398.     }
  399.  
  400.     /* we have to draw if four times for wraparound */
  401.     sx &= 0xff;
  402.     sy &= 0xff;
  403.     copybitmap(bitmap,bsbitmap,
  404.             flipx,flipy,
  405.             sx,sy,
  406.             &Machine->drv->visible_area,TRANSPARENCY_COLOR,bgpen);
  407.     copybitmap(bitmap,bsbitmap,
  408.             flipx,flipy,
  409.             sx-256,sy,
  410.             &Machine->drv->visible_area,TRANSPARENCY_COLOR,bgpen);
  411.     copybitmap(bitmap,bsbitmap,
  412.             flipx,flipy,
  413.             sx-256,sy-256,
  414.             &Machine->drv->visible_area,TRANSPARENCY_COLOR,bgpen);
  415.     copybitmap(bitmap,bsbitmap,
  416.             flipx,flipy,
  417.             sx,sy-256,
  418.             &Machine->drv->visible_area,TRANSPARENCY_COLOR,bgpen);
  419. }
  420.  
  421.  
  422. void cclimber_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  423. {
  424.     int offs;
  425.  
  426.  
  427.     /* for every character in the Video RAM, check if it has been modified */
  428.     /* since last time and update it accordingly. */
  429.     for (offs = videoram_size - 1;offs >= 0;offs--)
  430.     {
  431.         if (dirtybuffer[offs])
  432.         {
  433.             int sx,sy,flipx,flipy;
  434.  
  435.  
  436.             dirtybuffer[offs] = 0;
  437.  
  438.             sx = offs % 32;
  439.             sy = offs / 32;
  440.             flipx = colorram[offs] & 0x40;
  441.             flipy = colorram[offs] & 0x80;
  442.             /* vertical flipping flips two adjacent characters */
  443.             if (flipy) sy ^= 1;
  444.  
  445.             if (flipscreen[0])
  446.             {
  447.                 sx = 31 - sx;
  448.                 flipx = !flipx;
  449.             }
  450.             if (flipscreen[1])
  451.             {
  452.                 sy = 31 - sy;
  453.                 flipy = !flipy;
  454.             }
  455.  
  456.             drawgfx(tmpbitmap,Machine->gfx[(colorram[offs] & 0x10) ? 1 : 0],
  457.                     videoram[offs] + 8 * (colorram[offs] & 0x20),
  458.                     colorram[offs] & 0x0f,
  459.                     flipx,flipy,
  460.                     8*sx,8*sy,
  461.                     0,TRANSPARENCY_NONE,0);
  462.         }
  463.     }
  464.  
  465.  
  466.     /* copy the temporary bitmap to the screen */
  467.     {
  468.         int scroll[32];
  469.  
  470.  
  471.         if (flipscreen[0])
  472.         {
  473.             for (offs = 0;offs < 32;offs++)
  474.             {
  475.                 scroll[offs] = -cclimber_column_scroll[31 - offs];
  476.                 if (flipscreen[1]) scroll[offs] = -scroll[offs];
  477.             }
  478.         }
  479.         else
  480.         {
  481.             for (offs = 0;offs < 32;offs++)
  482.             {
  483.                 scroll[offs] = -cclimber_column_scroll[offs];
  484.                 if (flipscreen[1]) scroll[offs] = -scroll[offs];
  485.             }
  486.         }
  487.  
  488.         copyscrollbitmap(bitmap,tmpbitmap,0,0,32,scroll,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  489.     }
  490.  
  491.  
  492.     /* update the "big sprite" */
  493.     {
  494.         int newcol;
  495.         static int lastcol;
  496.  
  497.  
  498.         newcol = cclimber_bigspriteram[1] & 0x07;
  499.  
  500.         for (offs = cclimber_bsvideoram_size - 1;offs >= 0;offs--)
  501.         {
  502.             int sx,sy;
  503.  
  504.  
  505.             if (bsdirtybuffer[offs] || newcol != lastcol)
  506.             {
  507.                 bsdirtybuffer[offs] = 0;
  508.  
  509.                 sx = offs % 16;
  510.                 sy = offs / 16;
  511.  
  512.                 drawgfx(bsbitmap,Machine->gfx[2],
  513.                         cclimber_bsvideoram[offs],newcol,
  514.                         0,0,
  515.                         8*sx,8*sy,
  516.                         0,TRANSPARENCY_NONE,0);
  517.             }
  518.  
  519.         }
  520.  
  521.         lastcol = newcol;
  522.     }
  523.  
  524.  
  525.     if (cclimber_bigspriteram[0] & 1)
  526.         /* draw the "big sprite" below sprites */
  527.         drawbigsprite(bitmap);
  528.  
  529.  
  530.     /* Draw the sprites. Note that it is important to draw them exactly in this */
  531.     /* order, to have the correct priorities. */
  532.     for (offs = spriteram_size - 4;offs >= 0;offs -= 4)
  533.     {
  534.         int sx,sy,flipx,flipy;
  535.  
  536.  
  537.         sx = spriteram[offs + 3];
  538.         sy = 240 - spriteram[offs + 2];
  539.         flipx = spriteram[offs] & 0x40;
  540.         flipy = spriteram[offs] & 0x80;
  541.         if (flipscreen[0])
  542.         {
  543.             sx = 240 - sx;
  544.             flipx = !flipx;
  545.         }
  546.         if (flipscreen[1])
  547.         {
  548.             sy = 240 - sy;
  549.             flipy = !flipy;
  550.         }
  551.  
  552.         drawgfx(bitmap,Machine->gfx[spriteram[offs + 1] & 0x10 ? 4 : 3],
  553.                 (spriteram[offs] & 0x3f) + 2 * (spriteram[offs + 1] & 0x20),
  554.                 spriteram[offs + 1] & 0x0f,
  555.                 flipx,flipy,
  556.                 sx,sy,
  557.                 &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  558.     }
  559.  
  560.  
  561.     if ((cclimber_bigspriteram[0] & 1) == 0)
  562.         /* draw the "big sprite" over sprites */
  563.         drawbigsprite(bitmap);
  564. }
  565.  
  566.  
  567.  
  568. void swimmer_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  569. {
  570.     int offs;
  571.  
  572.  
  573.     if (palette_recalc())
  574.     {
  575.         memset(dirtybuffer,1,videoram_size);
  576.         memset(bsdirtybuffer,1,cclimber_bsvideoram_size);
  577.     }
  578.  
  579.     /* for every character in the Video RAM, check if it has been modified */
  580.     /* since last time and update it accordingly. */
  581.     for (offs = videoram_size - 1;offs >= 0;offs--)
  582.     {
  583.         if (dirtybuffer[offs])
  584.         {
  585.             int sx,sy,flipx,flipy,color;
  586.  
  587.  
  588.             dirtybuffer[offs] = 0;
  589.  
  590.             sx = offs % 32;
  591.             sy = offs / 32;
  592.             flipx = colorram[offs] & 0x40;
  593.             flipy = colorram[offs] & 0x80;
  594.             /* vertical flipping flips two adjacent characters */
  595.             if (flipy) sy ^= 1;
  596.  
  597.             if (flipscreen[0])
  598.             {
  599.                 sx = 31 - sx;
  600.                 flipx = !flipx;
  601.             }
  602.             if (flipscreen[1])
  603.             {
  604.                 sy = 31 - sy;
  605.                 flipy = !flipy;
  606.             }
  607.  
  608.             color = (colorram[offs] & 0x0f) + 0x10 * palettebank;
  609.             if (sx >= 24 && sidepanel_enabled)
  610.             {
  611.                 color += 32;
  612.             }
  613.  
  614.             drawgfx(tmpbitmap,Machine->gfx[0],
  615.                     videoram[offs] + ((colorram[offs] & 0x10) << 4),
  616.                     color,
  617.                     flipx,flipy,
  618.                     8*sx,8*sy,
  619.                     0,TRANSPARENCY_NONE,0);
  620.         }
  621.     }
  622.  
  623.  
  624.     /* copy the temporary bitmap to the screen */
  625.     {
  626.         int scroll[32];
  627.  
  628.  
  629.         if (flipscreen[1])
  630.         {
  631.             for (offs = 0;offs < 32;offs++)
  632.                 scroll[offs] = cclimber_column_scroll[31 - offs];
  633.         }
  634.         else
  635.         {
  636.             for (offs = 0;offs < 32;offs++)
  637.                 scroll[offs] = -cclimber_column_scroll[offs];
  638.         }
  639.  
  640.         copyscrollbitmap(bitmap,tmpbitmap,0,0,32,scroll,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  641.     }
  642.  
  643.  
  644.     /* update the "big sprite" */
  645.     {
  646.         int newcol;
  647.         static int lastcol;
  648.  
  649.  
  650.         newcol = cclimber_bigspriteram[1] & 0x03;
  651.  
  652.         for (offs = cclimber_bsvideoram_size - 1;offs >= 0;offs--)
  653.         {
  654.             int sx,sy;
  655.  
  656.  
  657.             if (bsdirtybuffer[offs] || newcol != lastcol)
  658.             {
  659.                 bsdirtybuffer[offs] = 0;
  660.  
  661.                 sx = offs % 16;
  662.                 sy = offs / 16;
  663.  
  664.                 drawgfx(bsbitmap,Machine->gfx[2],
  665.                         cclimber_bsvideoram[offs] + ((cclimber_bigspriteram[1] & 0x08) << 5),
  666.                         newcol,
  667.                         0,0,
  668.                         8*sx,8*sy,
  669.                         0,TRANSPARENCY_NONE,0);
  670.             }
  671.  
  672.         }
  673.  
  674.         lastcol = newcol;
  675.     }
  676.  
  677.  
  678.     if (cclimber_bigspriteram[0] & 1)
  679.         /* draw the "big sprite" below sprites */
  680.         drawbigsprite(bitmap);
  681.  
  682.  
  683.     /* Draw the sprites. Note that it is important to draw them exactly in this */
  684.     /* order, to have the correct priorities. */
  685.     for (offs = spriteram_size - 4;offs >= 0;offs -= 4)
  686.     {
  687.         int sx,sy,flipx,flipy;
  688.  
  689.  
  690.         sx = spriteram[offs + 3];
  691.         sy = 240 - spriteram[offs + 2];
  692.         flipx = spriteram[offs] & 0x40;
  693.         flipy = spriteram[offs] & 0x80;
  694.         if (flipscreen[0])
  695.         {
  696.             sx = 240 - sx;
  697.             flipx = !flipx;
  698.         }
  699.         if (flipscreen[1])
  700.         {
  701.             sy = 240 - sy;
  702.             flipy = !flipy;
  703.         }
  704.  
  705.         drawgfx(bitmap,Machine->gfx[1],
  706.                 (spriteram[offs] & 0x3f) | (spriteram[offs + 1] & 0x10) << 2,
  707.                 (spriteram[offs + 1] & 0x0f) + 0x10 * palettebank,
  708.                 flipx,flipy,
  709.                 sx,sy,
  710.                 &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  711.     }
  712.  
  713.  
  714.     if ((cclimber_bigspriteram[0] & 1) == 0)
  715.         /* draw the "big sprite" over sprites */
  716.         drawbigsprite(bitmap);
  717. }
  718.